﻿namespace NebulaServer.Config
{
    using System.ComponentModel.Composition;
    using System.Xml.Linq;
    using System;
    using System.Linq;
    using System.Collections.Generic;
    using System.Text.RegularExpressions;

    [Export("Config", typeof(IConfig))]
    [PartCreationPolicy(CreationPolicy.NonShared)]
    public sealed class ConfigQuery : IConfig
    {
        private readonly XDocument _document = XDocument.Load(AppDomain.CurrentDomain.GetData("DataDirectory") + "/Config.xml");

        public T Get<T>(string id)
        {
            var data = from element in _document.Descendants("Data")
                       where (string)element.Attribute("id") == id
                       select element;
            if (data == null) return default(T);
            string type = (string)data.SingleOrDefault().Attribute("type");
            Type genericType = typeof(T);
            if (genericType.Name.ToLower().Contains(type.ToLower()))
            {
                switch (type)
                {
                    case "int":
                        return (T)(object)int.Parse(data.SingleOrDefault().Attribute("value").Value);

                    case "string":
                        return (T)(object)data.SingleOrDefault().Attribute("value").Value;

                    case "bool":
                        return (T)(object)Convert.ToBoolean(data.SingleOrDefault().Attribute("value").Value);

                    case "single":
                        return (T)(object)Single.Parse(data.SingleOrDefault().Attribute("value").Value);
                }
            }
            return default(T);
        }

        public Dictionary<string, T> GetMulti<T>(string id)
        {
            Dictionary<string, T> dictionary = new Dictionary<string, T>();
            var data = from element in _document.Descendants("Data")
                       where (string)element.Attribute("id") == id
                       select element;
            if (data == null) return default(Dictionary<string, T>);
            string type = (string)data.SingleOrDefault().Attribute("type");
            Type genericType = typeof(T);
            return genericType.Name.ToLower().Contains(type.ToLower()) ?
                RecupValue<T>(id, data.SingleOrDefault().Attribute("value").Value, genericType) : dictionary;
        }

        private Dictionary<string, T> RecupValue<T>(string id, string data, Type type)
        {
            Dictionary<string, T> results = new Dictionary<string, T>();
            const string pattern = @"(?<value>[^@]+)";
            var value = from Match match in Regex.Matches(data, pattern)
                        select match;
            int i = 0;
            foreach (var match in value)
            {
                results.Add(id + "_" + i, (T)(object)match.Value);
                i++;
            }
            return results;
        }
    }
}